--[[
    牌的一些算法
    getCardType          --获取牌型的方法
    getCardTypeText   --获取牌型文本的方法
    compareCardType    --获取比牌方法
    getWinRateForHoldCards  --获取各自手牌的胜率

    M.s_pais = {
        0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,   -- spades  黑桃
        0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,   -- hearts 红心
        0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,   -- clubs 梅花
        0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,   -- diamonds 方块
    }
--]]


local MIN_CARD_NUM = 2 --最小牌是2
-- 方块 梅花 红桃 黑桃
local CARD_COLOR_TYPE = {
    DIAMOND = 3,
    CLUB = 2,
    HEART = 1,
    SPADE = 0
}
--牌颜色类型文本
local CARD_COLOR_TYPE_TEXT = {
    [CARD_COLOR_TYPE.DIAMOND] = '方块',
    [CARD_COLOR_TYPE.CLUB] = '梅花',
    [CARD_COLOR_TYPE.HEART] = '红桃',
    [CARD_COLOR_TYPE.SPADE] = '黑桃',
}
--牌数字文本
local CARD_NUM_TEXT = {
    [1] = 'A',
    [2] = '2',
    [3] = '3',
    [4] = '4',
    [5] = '5',
    [6] = '6',
    [7] = '7',
    [8] = '8',
    [9] = '9',
    [10] = '10',
    [11] = 'J',
    [12] = 'Q',
    [13] = 'K',
    [14] = 'A',
}
-- 牌型
local CARD_TYPE = {
    ROYAL_STRAIGHT_FLUSH = 9,
    STRAIGHT_FLUSH = 8,
    FOUR_OF_A_KIND = 7,
    FULL_HOUSE = 6,
    FLUSH = 5,
    STRAIGHT = 4,
    THREE_OF_A_KIND = 3,
    TWO_PAIRS = 2,
    PAIR = 1,
    HIGH_CARD = 0,
    NONE = -1,
}
--牌型文本
local CARD_TYPE_TEXT = {
    [CARD_TYPE.ROYAL_STRAIGHT_FLUSH] = '皇家同花顺',
    [CARD_TYPE.STRAIGHT_FLUSH] = '同花顺',
    [CARD_TYPE.FOUR_OF_A_KIND] = '四条',
    [CARD_TYPE.FULL_HOUSE] = '葫芦',
    [CARD_TYPE.FLUSH] = '同花',
    [CARD_TYPE.STRAIGHT] = '顺子',
    [CARD_TYPE.THREE_OF_A_KIND] = '三条',
    [CARD_TYPE.TWO_PAIRS] = '两对',
    [CARD_TYPE.PAIR] = '对子',
    [CARD_TYPE.HIGH_CARD] = '高牌',
}



--浅copy
local function shallow_copy(orig)
    local copy
    if type(orig) == "table" then
        copy = {}
        for orig_key, orig_value in pairs(orig) do
            copy[orig_key] = orig_value
        end
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

--合并两个table
local mergeTb_ = function (tb1_, tb2_, dstTb_)
    local res = dstTb_ or {}
    if tb1_ then
        for _,V in pairs(tb1_) do
            table.insert(res, V)
        end
    end
    if tb2_ then
        for _,V in pairs(tb2_) do
            table.insert(res, V)
        end
    end
    return res
end

--table 裁切子数组
local sliceTb_ = function (tarTb_, startIndex, endIndex_)
    local res = {}
    endIndex_ = endIndex_ or #tarTb_
    for index,value in ipairs(tarTb_) do
        if index >= startIndex and index <= endIndex_ then
            table.insert(res,value)
        end
    end
    -- dumpTb(res)
    return res
end

local compareFun_ = function (objA_,objB_)
    if not objA_ or not objB_ then
        return false
    end
    -- 为nil的情况必须返回false
    -- 相等的情况必须返回false (lua要求的坑点)
    return objA_.sortNum > objB_.sortNum
end

--检测table数组的长度是否超过默认5（顺子，高牌，同花，最多比较5张）
local checkTbLenThanX_ = function (tarTb_, xNum_)
    xNum_ = xNum_ or 5
    local tmp_len = #tarTb_
    --超过 xNum_的牌置空
    if tmp_len > xNum_ then
        for i = xNum_+1, tmp_len do
            tarTb_[i] = nil
        end
    end
end

--获取最长的顺子(最多7张牌中)
local getMaxLengLink_ = function (cardData_)
    local tarRes = {}
    local lastCardNum_ = 0
    --首先判断有没有A
    if cardData_[1].sortNum == 14 then
        table.insert(cardData_, shallow_copy(cardData_[1]))
    end
    for i=#cardData_ ,1, -1 do
        if i == #cardData_ and cardData_[i].sortNum == 14 then
            lastCardNum_ = 1
            table.insert(tarRes, cardData_[i])
        else
            --如果是顺子，排序后数值是连续的
            if cardData_[i].sortNum - lastCardNum_ == 1 or lastCardNum_ == 0 then
                lastCardNum_ = cardData_[i].sortNum
                table.insert(tarRes, cardData_[i])
            elseif cardData_[i].sortNum - lastCardNum_ == 0 then
                --数值相等就只算一个数就可以
            else
                if #tarRes >= 5 then
                    break
                end
                --顺子牌数不够5个，重新开始计
                tarRes = {}
                lastCardNum_ = 0
                lastCardNum_ = cardData_[i].sortNum
                table.insert(tarRes, cardData_[i])
            end
        end
    end
    if #tarRes < 5 then
        tarRes = {}
    end
    -- dumpTb(tarRes,'getMaxLengLink_:')
    return tarRes
end


--牌值(逻辑牌值)比较
local sortNumCompare_ = function (cardData1_, cardData2_)
    local len1 = #cardData1_
    local len2 = #cardData2_
    if len1 ~= len2 then
        g.log:err("sortNumCompare_:", cardData1_, cardData2_)
        return len1 > len2 or -1
    end
    for i = 1, #cardData1_ do
        if cardData1_[i].sortNum > cardData2_[i].sortNum then
            return 1
        elseif cardData1_[i].sortNum < cardData2_[i].sortNum then
            return -1
        end
    end
    return 0
end


------------------------------------------------------------------

------------------------------------------------------------------
---
local M = class("CardAlgorithm")

function M:ctor()


end

function M:getCardTypeText(cardType_)
    print('牌型文本：'..CARD_TYPE_TEXT[cardType_])
    return CARD_TYPE_TEXT[cardType_]
end

function M:allCardsSidToCid_(sids_, dstCids_)
    local allCards = dstCids_ or {}
    for i,v in ipairs(sids_) do
        table.insert(allCards, self:cardSid2Cid_(v))
    end
    return allCards
end

--服务器下发的牌Sid转换为客户端牌Cid
function M:cardSid2Cid_(cardSid_)
    local hexCardNum_ = cardSid_
    local num = math.fmod(hexCardNum_,16) --取模 或者 hexCardNum_%16
    local color = math.modf(hexCardNum_/16) --取整 返回整数、余数

    local tmpNum = num == 1 and 14 or num -- 最小数值是2，最大数值是14(A)
    local resInt = (color) * 13 + tmpNum --花色 0 - 3

    print('cardSid_:'..hexCardNum_..'->'..CARD_COLOR_TYPE_TEXT[color]..CARD_NUM_TEXT[num]..'=>'..resInt)
    return resInt
end

--客户端牌Cid转换为服务端牌Sid
function M:cardCid2Sid_(cardCid_)
    local num = math.fmod(cardCid_,13) --取模 或者 cardCid_%13
    local color = math.modf(cardCid_/13) --取整 返回整数、余数
    if num == 0 or num == 1 then
        color = color - 1
        if num == 0 then
            num = 13
        end
    end
    color = color + 1
    local tarHexNum = color * 16 + num
    print('cardCid_:'..cardCid_..'->'..CARD_COLOR_TYPE_TEXT[color]..CARD_NUM_TEXT[num]..'=>'..string.format("%#x",tarHexNum))
    return resInt
end
-- cardCid2Sid_(24)

--获取牌型的内部方法
function M:getCardTypeInter_(allCardsCid_)
    local allCards = allCardsCid_
    local map = {} --所有牌的一个标记， true为有牌
    for i = 2, 53 do
        map[i]= false
    end
    for i,v in ipairs(allCards) do
        map[v] = true
    end
    local colorCountTb = {}  --每个花色的张数
    local colorLinkMaxTb = {} --每个花色的最大连接数
    local uniColorCountMax = 0 --全局同花色张数的最大值
    local uniColorLinkMax = 0 --全局同颜色连接数的最大值

    local tmpInitNum = MIN_CARD_NUM == 2 and 1 or MIN_CARD_NUM
    for colorV = 0, 3 do
        local tmp_count = 0;
        local tmp_link = 0;
        local tmp_link_Max = 0;
        for numV = tmpInitNum, 14 do
            local has_card = false
            if numV == 1 then
                -- 考虑 A2345的情况
                has_card = map[14 + colorV * 13]
            else
                has_card = map[numV + colorV * 13]
            end

            if has_card then
                tmp_link = tmp_link + 1
                tmp_link_Max = math.max(tmp_link, tmp_link_Max)
                if numV ~= 1 then
                    tmp_count = tmp_count + 1
                end
            else
                tmp_link = 0
            end
        end
        colorCountTb[colorV] = tmp_count
        colorLinkMaxTb[colorV] = tmp_link_Max
    end
    for colorV = 0, 3 do
        uniColorCountMax = math.max(colorCountTb[colorV], uniColorCountMax)
        uniColorLinkMax = math.max(colorLinkMaxTb[colorV], uniColorLinkMax)
    end


    local numLinkMax = 0 --最大的数字连接长度
    local sameNumTb = {} --每个数字重复的次数
    local tmp_num_link_max = 0
    for numV = tmpInitNum, 14 do
        local tmp_count = 0
        local tmp_has_card = false
        for colorV = 0, 3 do
            local has_card = false
            if numV == 1 then
                has_card = map[14 + colorV * 13]
            else
                has_card = map[numV + colorV * 13]
            end
            if has_card then
                tmp_has_card = true
                tmp_count = tmp_count + 1
            end
        end
        if numV ~= 1 then
            sameNumTb[numV] = tmp_count
        end
        if tmp_has_card then
            tmp_num_link_max = tmp_num_link_max + 1
            numLinkMax = math.max(tmp_num_link_max,numLinkMax)
        else
            tmp_num_link_max = 0
        end
    end

    --全局相同数字的张数的第一大值和第二大值
    local uniSameNumMaxFirst = 0
    local uniSameNumMaxSecond = 0
    for numV = MIN_CARD_NUM, 14 do
        if sameNumTb[numV] >= uniSameNumMaxFirst then
            uniSameNumMaxSecond = uniSameNumMaxFirst
            uniSameNumMaxFirst = sameNumTb[numV]
        elseif sameNumTb[numV] >= uniSameNumMaxSecond then
            uniSameNumMaxSecond = sameNumTb[numV]
        end
    end

    --返回结果
    local resType = CARD_TYPE.NONE;
    if uniColorLinkMax >= 5 then
        --皇家同花顺 或 同花顺
        --如果有同色AKQ 又是同花顺，那一定是皇家同花顺
        if (map[14] and map[13] and map[12] or
                map[14 + 13] and map[13 + 13] and map[12 + 13] or
                map[14 + 26] and map[13 + 26] and map[12 + 26] or
                map[14 + 39] and map[13 + 39] and map[12 + 39])
        then
            resType = CARD_TYPE.ROYAL_STRAIGHT_FLUSH;
        else
            resType = CARD_TYPE.STRAIGHT_FLUSH;
        end
    elseif uniSameNumMaxFirst == 4 then
        --四条
        resType = CARD_TYPE.FOUR_OF_A_KIND
    elseif uniSameNumMaxFirst == 3 and uniSameNumMaxSecond >=2 then
        --葫芦
        resType = CARD_TYPE.FULL_HOUSE
    elseif uniColorCountMax >= 5 then
        --同花
        resType = CARD_TYPE.FLUSH
    elseif numLinkMax >= 5 then
        --顺子
        resType = CARD_TYPE.STRAIGHT
    elseif uniSameNumMaxFirst == 3 then
        --三条
        resType = CARD_TYPE.THREE_OF_A_KIND
    elseif uniSameNumMaxFirst == 2 and uniSameNumMaxSecond == 2  then
        --两对
        resType = CARD_TYPE.TWO_PAIRS
    elseif uniSameNumMaxFirst == 2 then
        --对子
        resType = CARD_TYPE.PAIR
    else
        --高牌
        resType = CARD_TYPE.HIGH_CARD
    end

    print('牌型:'..resType)
    self:getCardTypeText(resType)
    return resType
end

function M:getCardType(holdCard_, publicCard_)
    local allCards = {}
    self:allCardsSidToCid_(holdCard_, allCards)
    self:allCardsSidToCid_(publicCard_, allCards)

    return self:getCardTypeInter_(allCards)
end


--分析牌数据
local analysisCardData_ = function(cids_)
    local res = {
        cidData = {},
        uniColor = { --每个花色对应的牌
            [0] = {},
            [1] = {},
            [2] = {},
            [3] = {}
        },
        smThourCards = {}, --4张牌
        smThreeCards = {}, --3张牌
        smSecondCards = {}, --2张牌
        smSingleCards = {}, --单牌
    };
    local smCardData = {}
    for _, cidV in ipairs(cids_) do
        local tmp_item = {
            rawCid = -1,
            num = -1,
            color = -1,
            sortNum = -1
        }
        tmp_item.rawCid = cidV
        local tmp_num = math.fmod(cidV,13) --取模 或者 hexCardNum_%16
        local tmp_color = math.modf(cidV/13) --取整 返回整数、余数
        if tmp_num == 0 or tmp_num == 1 then
            tmp_color = tmp_color - 1
        end

        tmp_item.num = tmp_num
        tmp_item.color = tmp_color
        tmp_num = tmp_num == 0 and 13 or tmp_num
        tmp_num = tmp_num == 1 and 14 or tmp_num
        tmp_item.sortNum = tmp_num
        --
        table.insert(res.cidData, tmp_item)
        table.insert(res.uniColor[tmp_color], tmp_item)
        if  not smCardData[tmp_num] then
            smCardData[tmp_num] = {}
        end
        table.insert(smCardData[tmp_num],tmp_item)
    end

    for _, numObj in pairs(smCardData) do
        if #numObj == 4 then
            table.insert(res.smThourCards,numObj[1])
        elseif #numObj == 3 then
            table.insert(res.smThreeCards,numObj[1])
        elseif #numObj == 2 then
            table.insert(res.smSecondCards,numObj[1])
        elseif #numObj == 1 then
            table.insert(res.smSingleCards,numObj[1])
        end
    end
    --对牌进行排序
    table.sort(res.cidData, compareFun_)
    table.sort(res.smThourCards, compareFun_)
    table.sort(res.smThreeCards, compareFun_)
    table.sort(res.smSecondCards, compareFun_)
    table.sort(res.smSingleCards, compareFun_)
    table.sort(res.uniColor[0], compareFun_)
    table.sort(res.uniColor[1], compareFun_)
    table.sort(res.uniColor[2], compareFun_)
    table.sort(res.uniColor[3], compareFun_)

    -- for _,value in pairs(res) do
    --     if type(value) == 'table' then
    --         dumpTb(value);
    --     end
    -- end
    -- dumpTb(res.smSingleCards,'单牌：');
    return res
end

--设置最小牌num，默认是2,常用还有6
function M:setMinCardNum(tarNum_)
    MIN_CARD_NUM = tarNum_
    print('setMinCardNum:',tarNum_)
end

--比较两个牌型大小
-- 1： 手牌1 > 手牌2
-- -1： 手牌1 < 手牌2
-- 0： 手牌1 = 手牌2
function M:compareCardTypeInter_(allCards1_, allCards2_)
    local  allCards1 = allCards1_
    local  allCards2 = allCards2_
    --牌型
    local cardType1 = self:getCardTypeInter_(allCards1)
    local cardType2 = self:getCardTypeInter_(allCards2)

    if cardType1 > cardType2 then
        return 1
    elseif cardType1 < cardType2 then
        return -1
    else
        --牌型相同的情况处理
        local analysisData1 = analysisCardData_(allCards1)
        local analysisData2 = analysisCardData_(allCards2)

        if cardType1 == CARD_TYPE.STRAIGHT_FLUSH then
            --同花顺，先比一下花色，花色相同再比较最大的牌就可以
            local tarColor --目标的花色
            local uniColorTb = analysisData1.uniColor --同一花色的牌
            for i=0, 3 do --花色从大到小
                if #uniColorTb[i] >= 5 then
                    tarColor = i
                    break
                end
            end

            local tarColor2 --目标的花色
            local uniColorTb = analysisData2.uniColor --同一花色的牌
            for i=0, 3 do --花色从大到小
                if #uniColorTb[i] >= 5 then
                    tarColor2 = i
                    break
                end
            end
            if tarColor > tarColor2 then
                return -1
            elseif tarColor < tarColor2 then
                return 1
            end

            local maxLengLink1_ = getMaxLengLink_(analysisData1.uniColor[tarColor]) --相同花色的牌
            local maxLengLink2_ = getMaxLengLink_(analysisData2.uniColor[tarColor])
            local tmpMaxLengLink1_ = sliceTb_(maxLengLink1_,#maxLengLink1_) --取相同花色的最后一张牌
            local tmpMaxLengLink2_ = sliceTb_(maxLengLink2_,#maxLengLink2_)
            return sortNumCompare_(tmpMaxLengLink1_, tmpMaxLengLink2_)
        elseif cardType1 == CARD_TYPE.FOUR_OF_A_KIND then
            --4条
            return  sortNumCompare_(analysisData1.smThourCards, analysisData2.smThourCards)
        elseif cardType1 == CARD_TYPE.FULL_HOUSE then
            --葫芦， 先比较3张谁大， 再比较2张谁大
            local smTC1_ = analysisData1.smThreeCards --相同值的3张
            local smTC2_ = analysisData2.smThreeCards
            local smSC1_ = analysisData1.smSecondCards --相同值的2张
            local smSC2_ = analysisData2.smSecondCards
            if #smTC1_ > 1 then
                local tmp_tc1 = sliceTb_(smTC1_,2)
                smSC1_ = mergeTb_(smSC1_, tmp_tc1)
                table.sort(smSC1_, compareFun_)
                smTC1_ = sliceTb_(smTC1_,1,1)
            end
            if #smTC2_ > 1 then
                local tmp_tc2 = sliceTb_(smTC2_,2)
                smSC2_ = mergeTb_(smSC2_, tmp_tc2)
                table.sort(smSC2_, compareFun_)
                smTC2_ = sliceTb_(smTC2_,1,1)
            end
            -- 比较
            local threeRes = sortNumCompare_(smTC1_, smTC2_)
            if threeRes ~= 0 then
                return threeRes
            else
                return sortNumCompare_(smSC1_,smSC2_)
            end
        elseif cardType1 == CARD_TYPE.FLUSH then
            --同花
            local tarColor
            local uniColorTb = analysisData1.uniColor
            for i=0,3 do
                if #uniColorTb[i] >= 5 then
                    tarColor = i
                    break
                end
            end
            checkTbLenThanX_(analysisData1.uniColor[tarColor]) --取5张同色牌
            checkTbLenThanX_(analysisData2.uniColor[tarColor])
            return sortNumCompare_(analysisData1.uniColor[tarColor],analysisData2.uniColor[tarColor])
        elseif cardType1 == CARD_TYPE.STRAIGHT then
            --顺子
            local maxLengLink1_ = getMaxLengLink_(analysisData1.cidData)
            local maxLengLink2_ = getMaxLengLink_(analysisData2.cidData)
            local tmpMaxLengLink1_ = sliceTb_(maxLengLink1_,#maxLengLink1_)
            local tmpMaxLengLink2_ = sliceTb_(maxLengLink2_,#maxLengLink2_)
            return sortNumCompare_(tmpMaxLengLink1_,tmpMaxLengLink2_)
        elseif cardType1 == CARD_TYPE.THREE_OF_A_KIND then
            --三张
            local threeRes = sortNumCompare_(analysisData1.smThreeCards,analysisData2.smThreeCards)
            if threeRes ~= 0 then
                return threeRes
            else
                --
                checkTbLenThanX_(analysisData1.smSingleCards,2) --取2张单牌
                checkTbLenThanX_(analysisData2.smSingleCards,2)
                return sortNumCompare_(analysisData1.smSingleCards, analysisData2.smSingleCards)
            end
        elseif cardType1 == CARD_TYPE.TWO_PAIRS then
            --两对
            local smSC1_ = analysisData1.smSecondCards
            local smSC2_ = analysisData2.smSecondCards
            if #smSC1_ > 2 then
                local tmp_sc1 = sliceTb_(smSC1_,3) --如果有3对，把第3对的牌放到单牌组里去比较
                analysisData1.smSingleCards = mergeTb_(analysisData1.smSingleCards,tmp_sc1)
                table.sort(analysisData1.smSingleCards, compareFun_)
                smSC1_ = sliceTb_(smSC1_,1,2)
            end
            if #smSC2_ > 2 then
                local tmp_sc2 = sliceTb_(smSC2_,3)
                analysisData2.smSingleCards = mergeTb_(analysisData2.smSingleCards,tmp_sc2)
                table.sort(analysisData2.smSingleCards, compareFun_)
                smSC2_ = sliceTb_(smSC2_,1,2)
            end

            local pairRes = sortNumCompare_(smSC1_, smSC2_)
            if pairRes ~= 0 then
                return pairRes
            else
                --从单牌里取一个比较大小
                checkTbLenThanX_(analysisData1.smSingleCards,1)
                checkTbLenThanX_(analysisData2.smSingleCards,1)
                return sortNumCompare_(analysisData1.smSingleCards,analysisData2.smSingleCards)
            end
        elseif cardType1 == CARD_TYPE.PAIR then
            local pairRes = sortNumCompare_(analysisData1.smSecondCards,analysisData2.smSecondCards)
            if pairRes ~= 0 then
                return pairRes
            else
                checkTbLenThanX_(analysisData1.smSingleCards,3)
                checkTbLenThanX_(analysisData2.smSingleCards,3)
                return sortNumCompare_(analysisData1.smSingleCards,analysisData2.smSingleCards)
            end

        elseif cardType1 == CARD_TYPE.HIGH_CARD then
            checkTbLenThanX_(analysisData1.smSingleCards)
            checkTbLenThanX_(analysisData2.smSingleCards)
            return sortNumCompare_(analysisData1.smSingleCards,analysisData2.smSingleCards)
        end
    end
end

--比较牌大小
function M:compareCardType(holdCard1_, holdCard2_, publicCard_)
    local allCards1 = {}
    local allCards2 = {}
    --g.log:err("compareCardType:", holdCard1_, holdCard2_, publicCard_)


    self:allCardsSidToCid_(holdCard1_, allCards1)
    self:allCardsSidToCid_(publicCard_, allCards1) --把公牌合到手牌中
    self:allCardsSidToCid_(holdCard2_, allCards2)
    self:allCardsSidToCid_(publicCard_, allCards2)

    if DEBUG_CODE then
        print('公共牌：')
        self:allCardsSidToCid_(publicCard_)
        print('手牌1：')
        self:allCardsSidToCid_(holdCard1_)
        print('手牌2：')
        self:allCardsSidToCid_(holdCard2_)
    end

    return self:compareCardTypeInter_(allCards1, allCards2)
end

--获取所有手牌各自的outs牌
--思路就是把没用过的牌都加到公牌上， 比较两个牌型大小
--返回各自的好牌列表
function M:getOutsForHoldCards(holdCards_, publicCard_)
    --g.log:err("getOutsForHoldCards:", holdCards_, publicCard_)
    local hcLen = #holdCards_
    if hcLen <= 1 then
        print('少于2组手牌传入，无法进行outs计算')
        return
    end
    --所有牌
    local allCards = {}
    local tmpMinNum = MIN_CARD_NUM == 2 and 2 or MIN_CARD_NUM
    local tmpKey
    for i=0, 3 do
        for j=tmpMinNum, 14 do
            tmpKey = i*16 + j
            allCards[tmpKey] = false
        end
    end
    -- dumpTb(allCards,'YXTTT1:')
    --所有手牌及公共牌
    local curAllCards = {}
    mergeTb_(publicCard_,nil,curAllCards)
    for _,valueNum in pairs(holdCards_) do
        mergeTb_(valueNum,nil, curAllCards)
    end
    for _, valueNum in pairs(curAllCards) do
        allCards[valueNum] = true
    end
    -- dumpTb(allCards,'YXTTT2:')
    local resOuts = {}
    for i=1, hcLen do
        table.insert(resOuts,{})
    end
    --计算outs
    for valueKey, valueNum in pairs(allCards) do
        if  not valueNum then
            local publicCardCp = shallow_copy(publicCard_) --公牌
            table.insert(publicCardCp, valueKey) --把没用到的牌放到公牌中
            local maxIndex = 1
            local hasMaxIndex = true
            for i=2, hcLen do
                local compareResTmp = self:compareCardType(holdCards_[maxIndex], holdCards_[i], publicCardCp)
                if compareResTmp == 1 then
                    -- maxIndex = maxIndex
                elseif compareResTmp == -1 then
                    maxIndex = i
                else
                    hasMaxIndex = false
                    break
                end
            end
            if hasMaxIndex then
                table.insert(resOuts[maxIndex], valueKey)
            end
        end
    end
    --dumpTb(resOuts,'outs 牌:')
    return resOuts
end

--获取所有手牌各自的胜率
function M:getWinRateForHoldCards(holdCards_, publicCard_)
    local resOuts = self:getOutsForHoldCards(holdCards_, publicCard_)
    local resRate = {}
    local sumNum = 0
    for _,valueNum in pairs(resOuts) do
        sumNum  = sumNum + #valueNum
    end
    for _,valueNum in pairs(resOuts) do
        local rateNum = #valueNum/sumNum
        local decimal = math.floor((rateNum*100)+0.5)*0.01
        table.insert(resRate,decimal)
    end
    print(resRate,'胜率:')
    return resRate
end







return M

